package com.wuchao.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wuchao.entity.Menu;
import com.wuchao.entity.Role;
import com.wuchao.entity.RoleMenu;
import com.wuchao.entity.User;
import com.wuchao.exception.BusinessException;
import com.wuchao.mapper.MenuMapper;
import com.wuchao.mapper.RoleMenuMapper;
import com.wuchao.mapper.UserMapper;
import com.wuchao.response.ResultCode;
import com.wuchao.service.UserService;
import com.wuchao.utils.JWTUtils;
import com.wuchao.utils.MD5Utils;
import com.wuchao.vo.UserVO;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author wuchao
 * @since 2022-03-29
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Override
    public Page<User> findUserList(Page<User> page, UserVO userVO) {
        List<User> userList = this.baseMapper.findUserList(page, userVO);
        page.setRecords(userList);
        return page;//难理解走过场，但是就是这样。设来设去
    }

    @Override
    public Page<User> findUserList1(Page<User> page, UserVO userVO) {
        List<User> userList1 = baseMapper.findUserList1(page, userVO);
        page.setRecords(userList1);
        return page;//走过场，多表联查必须这样写，用mapper实现，所以mapper
    }

    @Override
    public void exportUserExcel(HttpServletResponse response, List<User> users) throws IOException {
        //----- 写入excel文件
        String exportFileName = "TbUserInfo.xlsx";//入参名字
        response.setCharacterEncoding("UTF-8");//防止乱码
        response.setContentType("application/vnd.ms-excel");//设置导出格式
        //设置导出名称
        response.addHeader("Content-Disposition", "attachment;filename=" + exportFileName);
        //执行操作
        EasyExcel.write(response.getOutputStream(), User.class)
                .sheet("用户信息")
                //自动列宽 合并单元格等
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                .doWrite(users);//需要导出的内容，最后
    }

    /**
     * 返回令牌token
     * @param username
     * @param password
     * @return
     */
  /*  @Override
    public String login(String username, String password) {
       User user= this.baseMapper.loadUserByUsername(username);//1先拿信息
        String token = null;
        if(user!=null) {//非空判断，预防空指针
            //2拿出信息和盐
            String salt = user.getSalt();
            String userpassword = user.getPassword();
            //3加密来的密码，生成新密码，防止泄露
            String encryptionpwd = MD5Utils.md5Encryption(password, salt);//闯进来的是密码
            //4比对2次密码是否相等 生成token
            if (encryptionpwd.equals(userpassword)) {
                token = JWTUtils.sign(username, encryptionpwd);//注意这里容易报错，需要加盐后的密码
            }else{
                throw  new BusinessException(//密码错误---业务逻辑
                        ResultCode.PARAM_NOT_VALID.getCode(),ResultCode.PARAM_NOT_VALID.getMessage());
            }
        }else{
            throw  new BusinessException(//账号错误
                    ResultCode.PARAM_NOT_VALID.getCode(),ResultCode.PARAM_NOT_VALID.getMessage());
        }
        //5把 生成的token赋予shiro管理认真权限
        return token;
    }*/
    @Override
    public String login(String username, String password) {
        //定义一个token进行返回
        String token = null;
        //1.根据用户名查询用户信息
        User user = this.baseMapper.loadUserByUsername(username);
        if(user!=null){
//2.需要获取用户的密码跟盐
            String salt = user.getSalt();
            String userPassword = user.getPassword();
            //3.对原始密码进行加密加盐的操作
            String encryptionPassword = MD5Utils.md5Encryption(password, salt);
            //4.对比数据库的密码和加密之后的密码,判断是否相等
            System.out.println("到这里了");
            if(userPassword.equals(encryptionPassword)){//encryptionPassword123456
                System.out.println("密码没问题");
                //5.相等则生成token
                //昨天的代码这里有bug，需要改成encryptionPassword,不然直接报错
                token = JWTUtils.sign(username, encryptionPassword);
                //6.还需要将token存入到shiro的登录管理器中
                /*JWTToken jwtToken = new JWTToken(token);
                try {
                    SecurityUtils.getSubject().login(jwtToken);
                } catch (AuthenticationException e) {
                    throw new BusinessException(ResultCode.NO_PERMISSION.getCode(),
                            ResultCode.NO_PERMISSION.getMessage());
                }*/
            }else{
                System.out.println("密码有问题");
                throw new BusinessException(ResultCode.USER_CREDENTIALS_ERROR.getCode(),
                        ResultCode.USER_CREDENTIALS_ERROR.getMessage());
            }
        }else{
            throw new BusinessException(ResultCode.USER_ACCOUNT_NOT_EXIST.getCode(),
                    ResultCode.USER_ACCOUNT_NOT_EXIST.getMessage());
        }
        return token;
    }

    @Override
    public User loadUserByUsername(String username) {
        return this.baseMapper.loadUserByUsername(username);
    }

    @Override
    public List<Role> findRolesById(Long id) {

        return  baseMapper.findRolesById(id);


    }
@Resource
    RoleMenuMapper roleMenuMapper;
    @Resource
    MenuMapper menuMapper;
    @Override
    public List<Menu> findMenuByRoles(List<Role> roles) {
        List<Menu> menus=new ArrayList<>();
        if(!CollectionUtils.isEmpty(roles)){
            Set<Long> menuIds=new HashSet<>();//存放用户的菜单id
            List<RoleMenu> roleMenus;
            for (Role role : roles) {
                //根据角色的id获取userRole中间表的菜单id
                roleMenus= roleMenuMapper.selectByRoleId(role.getId());
                if(!CollectionUtils.isEmpty(roleMenus)){
                    for (RoleMenu roleMenu : roleMenus) {
                        menuIds.add(roleMenu.getMenuId());
                    }
                }
            }
            if(!CollectionUtils.isEmpty(menuIds)){
                for (Long menuId : menuIds) {
                    //该用户所有的菜单
                    Menu menu = menuMapper.selectByPrimaryKey(menuId);
                    if(menu!=null){
                        menus.add(menu);
                    }
                }
            }
        }
        return menus;
    }

}
